package com.gin.kotlin.no_gay_alliance.base

import android.content.Context
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.rxjava3.RxPreferenceDataStoreBuilder
import androidx.datastore.rxjava3.RxDataStore
import com.gin.kotlin.no_gay_alliance.app.App
import io.reactivex.rxjava3.core.Single
import kotlinx.coroutines.ExperimentalCoroutinesApi

/**
 * DataStore设置值
 * @param T 值类型
 * @receiver RxDataStore<Preferences>
 * @param preferencesKey Preferences.Key<T>
 * @param value T
 * @return Single<Preferences>
 */
@OptIn(ExperimentalCoroutinesApi::class)
fun <T> RxDataStore<Preferences>.setValue(preferencesKey: Preferences.Key<T>, value: T) =
    updateDataAsync { Single.just(it.toMutablePreferences().also { p -> p[preferencesKey] = value }) }

/**
 * DataStore移除值
 * @param T Any?
 * @receiver RxDataStore<Preferences>
 * @param preferencesKey Preferences.Key<T>
 * @return Single<Preferences>
 */
@OptIn(ExperimentalCoroutinesApi::class)
fun <T> RxDataStore<Preferences>.removeValue(preferencesKey: Preferences.Key<T>) =
    updateDataAsync { Single.just(it.toMutablePreferences().also { p -> p.remove(preferencesKey) }) }

/**
 * DataStore获取值
 * @param T Any
 * @receiver RxDataStore<Preferences>
 * @param preferencesKey Preferences.Key<T>
 * @param defaultValue T
 * @return T
 */
@OptIn(ExperimentalCoroutinesApi::class)
fun <T : Any> RxDataStore<Preferences>.getValue(preferencesKey: Preferences.Key<T>, defaultValue: T) = data().map { it[preferencesKey] ?: defaultValue }.blockingFirst()

class DatastoreUtils {
    companion object {
        private const val DEFAULT_STORE = "default_store"
        private val map = hashMapOf<String, RxDataStore<Preferences>>()

        /**
         * 获取DataStore实例
         * @param context Context
         * @param name String
         * @return RxDataStore<Preferences>
         */
        fun obtain(name: String = DEFAULT_STORE, context: Context = App.INSTANCE) = map[name]
            ?: RxPreferenceDataStoreBuilder(context, name).build().also { map[name] = it }
    }
}